home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / tex / lametex_.z / lametex_ / lametex / src / format.ps < prev    next >
Encoding:
Text File  |  1992-09-19  |  10.9 KB  |  428 lines

  1. %! This is a PostScript library meant to be printed only with other files %%%
  2. %% Postscript Code by Jonathan Monsarrat Copyright 1992
  3. %% permission given for anything except selling this or deleting the header.
  4. %% This is the LameTeX Formatter, uses the LaTeX language
  5. % Depends on "EndPage" and "StartPage" to be set up by a page formatter
  6.  
  7. /formatdict 100 dict def   % This should be 77?
  8.  
  9. formatdict begin
  10. /wlist 100 array def     % Maximum of 100 words on a line
  11. %% Better give these variables default values in case we try to
  12. %% do an EndPage but they have not yet been defined
  13.  
  14. /baselineskip 200 def /wlen 0 def /baselineskip 0 def /bottommargin 0 def
  15. /parindent 0 def /justify 0 def /rightmargin 0 def /leftmargin 0 def
  16. /topmargin 0 def /parskip 0 def /newfontcmd 1 def /para 0 def
  17. /vtotal 0 def /wordlen 0 def /ypos 0 def /ytemp 0 def
  18.  
  19. %%%%%%%%%%%%%%%%    num   InitWord    -  %%%%%%%%%%%%%%%%%%%%%%%
  20. % InitWord takes an setflat values and flattens the current path
  21. % It also defines some globals that will get "NextWord" up and running
  22. /InitWord
  23. {
  24.   /xpos currentflat def % Save current flatness
  25.   PageShape setflat flattenpath 
  26.   % gsave stroke grestore  % Uncomment this line to show the margin path
  27.   /coords Approx def
  28.   pathbbox   % It the current path is bigger than the margins, widen them!
  29.   dup TM gt { /TM exch def } { pop } ifelse
  30.   dup RM gt { /RM exch def } { pop } ifelse
  31.   dup BM lt { /BM exch def } { pop } ifelse
  32.   dup LM lt { /LM exch def } { pop } ifelse
  33.  
  34.   xpos setflat   % Restore flatness.
  35.   false fontnames newfontcmd get cvx exec
  36.   /xlocs [ ] def 
  37.   /welem 1 def /wlen 0 def /woids 0 def 
  38.   /eslot LM def 
  39.   /ypos TM topmargin sub def
  40.   /vtotal 0 def
  41.   /xpos 0 def /nxpos 0 def
  42.   wlist 0 [ newfontcmd false ] put
  43.   /wtemp 0 def
  44.   NextSpace pop 
  45. } bind def
  46.  
  47. %%%%%%%%%%%%%%%%%%%%%  -   NewXSpace    bool %%%%%%%%%%%%%%%%%%%%%%
  48. % If there's "room on the bottom" as defined by xlocs, check to see if
  49. % there's "room on the top" as defined by NewXSpace. Returns success boolean.
  50. /NewXSpace
  51. {
  52.   nxpos newxlocs length 1 sub lt 
  53.   {
  54.     newxlocs nxpos 2 getinterval {} forall exch
  55.     /nxpos nxpos 2 add def  
  56. % If there's any intersection of top and bottom 'good places' set bslot, eslot
  57.     dup xa le { pop xa } if leftmargin add /bslot exch def 
  58.     dup xb ge { pop xb } if rightmargin sub /eslot exch def 
  59.     bslot eslot lt { true } { NewXSpace } ifelse 
  60.   }
  61.   {
  62.     false 
  63.   } ifelse 
  64. } bind def
  65.  
  66. %%%%%%%%%%%%%%%  -   NextSpace   bool  %%%%%%%%%%%%%%%%%%%%%%
  67. % NextSpace defines the next space available for writing by
  68. % setting ypos to the Y location and bslot and eslot to the beginning
  69. % and end of the next open text writing area. Returns success boolean.
  70. /NextSpace
  71. {
  72.    xpos xlocs length 1 sub lt      % are there any X's left on current line
  73.    {
  74.       /xa xlocs xpos get def 
  75.       /xb xlocs xpos 1 add get def 
  76.       NewXSpace 
  77.       { true } 
  78.       { 
  79.         /nxpos 0 def 
  80.         /xpos xpos 2 add def 
  81.         NextSpace 
  82.       } ifelse 
  83.    }
  84.    {
  85.       ypos  % Leave on the stack for later comparison
  86.       /ypos ypos
  87.       vspace 0 eq
  88.       {
  89.         baselineskip para { parskip add } if /vtotal baselineskip def
  90.       }
  91.       {
  92.         vspace /vspace 0 def
  93.       } ifelse
  94.       sub def 
  95.       ypos BM bottommargin add ge 
  96.       {
  97.         /newxlocs coords 3 -1 roll 4 add true CheeseWhiz def 
  98.         /xlocs coords ypos 4 sub true CheeseWhiz def 
  99.         /xpos 0 def /nxpos 0 def 
  100.         NextSpace 
  101.       }
  102.       {
  103.         pop false
  104.       } ifelse 
  105.    } ifelse 
  106.   % if we're doing a paragraph and the NextSpace isn't big enough
  107.   % for the indentation, then choose a new space.
  108.   % if found-space and para and justify
  109.   dup para justify 102 eq and and   % 102 is ascii 'f' for FULL JUSTIFY
  110.   { /bslot bslot parindent add def bslot eslot gt 
  111.         { pop NextSpace pop 
  112.         } if
  113.   } if
  114.   /para false def 
  115. } bind def
  116.  
  117. %%%%%%%%%%%%%%%%%%%%%%% -  PrintWordList  -  %%%%%%%%%%%%%%%%%%%%%%%%%%%%
  118. % PrintWordList prints the words stored in array "wlist" at Y location ypos
  119. % with full justification between X locations bslot and eslot.
  120. /PrintWordList
  121. {
  122.   /vtotal 0 def
  123.   woids 0 ne
  124.   { 
  125.     % Legal values for /justify are (l)eft (r)ight (f)ull (c)enter in ASCII
  126.     justify 99 eq  % 99 is ascii 'c' for CENTERED
  127.     {
  128.       bslot eslot bslot sub wlen sub 2 div add ypos moveto
  129.     }
  130.     {
  131.       bslot justify 114 eq { eslot bslot sub wlen sub add } if   % 114 is 'r'
  132.       ypos moveto 
  133.     } ifelse
  134.     /sp eslot bslot sub wlen sub woids div def
  135.     0 1 welem 1 sub 
  136.     {
  137.       wlist exch get
  138.       dup type /stringtype eq
  139.       {
  140.         SHOWIT ( ) stringwidth pop 0 rmoveto 
  141.         justify 102 eq { sp 0 rmoveto } if  % 102 is ascii 'f'
  142.       }
  143.       {
  144.         dup type /arraytype eq
  145.         {
  146.           { } forall
  147.           {
  148.              ( ) stringwidth pop neg 0 rmoveto 
  149.              justify 102 eq { sp neg 0 rmoveto } if  % 102 is ascii 'f'
  150.       } if
  151.           fontnames exch get cvx true exch exec
  152.     }
  153.         {
  154.            0 rmoveto
  155.     } ifelse
  156.       } ifelse 
  157.     } for
  158.      wlist 0 [ newfontcmd false ] put
  159.      /welem 1 def /wlen 0 def /woids 0 def 
  160.   } if
  161. } def
  162.  
  163. %%%%%%%%%%%%%%%%%%%%%%%%%  -   PrintClose  -  %%%%%%%%%%%%%%%%%%%%%%%%
  164. % PrintClose prints the words stored in the array "wlist" at Y location ypos
  165. % starting at X location bslot with left justification.
  166. /PrintClose
  167. {
  168.   justify 102 eq  % 102 is ascii 'f'
  169.   {
  170.     /justify 108 def % 108 is ascii 'l' for flushleft
  171.     PrintWordList 
  172.     /justify 102 def
  173.   }
  174.   {
  175.     PrintWordList 
  176.   } ifelse
  177. } bind def
  178.  
  179. %%%%%%%%%%%%%%%%  string  Parse  - %%%%%%%%%%%%%%%%%%%%%%%%
  180. % Parse breaks a string into words based on spaces, passing each to NextWord
  181. /Parse
  182. {
  183.    dup length 0 eq   % kill extra spaces by shaving them until null string
  184.    { pop }
  185.    { ( ) search { Parse pop Parse } { NW } ifelse } ifelse
  186. } bind def
  187.  
  188. %%%%%%%%%%%%%%%%%%%%%%%  string  NextWord  - %%%%%%%%%%%%%%%%%%%%%%
  189. % NextWord appends the string to an array of words
  190. % and tries to place the text inside an arbitrary path (which was analyzed
  191. % by InitWord). It's meant to be an iterative part of a long list of
  192. % "string NextWord" sets which justifies text inside any closed path.
  193. /NextWord
  194. {
  195.    /word exch def word stringwidth pop /wordlen exch def
  196.    GrabSpace
  197. } bind def
  198.  
  199. %%%%%%%%%% Takes a horizontal distance and a string for positioning
  200. /GrabSpace
  201. {
  202.    wordlen wlen add 
  203.    eslot bslot sub gt 
  204.    {
  205.      PrintWordList word type /stringtype ne { /welem 0 def } if
  206.      NextSpace 
  207.      {
  208.        GrabSpace
  209.      } 
  210.      {
  211.        % Have reached end of page
  212.        ENDPAGE STARTPAGE
  213.        /ypos baselineskip ypos add def /vtotal baselineskip def NEWLINE
  214.        GrabSpace
  215.      } ifelse 
  216.    }
  217.    {
  218.      word type /stringtype eq
  219.      { 
  220.        wlist welem word put /welem welem 1 add def
  221.        /wlen wlen ( ) stringwidth pop add def
  222.        /woids woids 1 add def 
  223.       } if
  224.       /wlen wlen wordlen add def 
  225.    } ifelse 
  226. } def
  227.  
  228. %%%%%%%%%%%%%%%% xwidth HSpace  - %%%%%%%%%%%%%%
  229. % Adds to the current wlen and adds the right thing in the wlist array
  230. /HSpace
  231. {
  232.    dup wlen add /wlen exch def
  233.    wlist welem 3 -1 roll put /welem welem 1 add def
  234. } bind def
  235.  
  236.  
  237. %%%%%%%%%%%%%%%%% size type NewFont %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  238. % NewFont sets a new font, given a type and size
  239. /NewFont
  240. {
  241.   { } forall /word exch def /newfontcmd exch def 
  242.   word wlist welem [ newfontcmd 5 -1 roll ] put /welem welem 1 add def
  243.   false fontnames newfontcmd get cvx exec
  244.   word true eq woids 0 gt and
  245.   { 
  246.        /wlen wlen ( ) stringwidth pop sub def
  247.   } if
  248. } bind def
  249.  
  250. %%%%%%%%%%%%%% x y READJUST %%%%%%%%%%%%%%
  251. % Readjusts the line down by given amountif big fonts are being placed
  252. % in a small vertical space, and across if a horizontal space is being added.
  253. /READJUST
  254. {
  255.    wtemp type /arraytype eq    % Don't do recursive READJUSTs
  256.    {
  257.       pop pop
  258.    }
  259.    {
  260.       /vspace exch def /wordlen exch def
  261.       /welem welem 1 sub def
  262.       GrabSpace vspace 0 ne { SKIPLINE } if % Skip to a new page if needed
  263.       /wtemp wlist def /woids 0 def /wlen 0 def
  264.       0 1 welem /welem 0 def
  265.       {
  266.         wtemp exch get
  267.         dup type /stringtype eq
  268.         {
  269.           NextWord
  270.         }
  271.         {
  272.            dup type /arraytype eq
  273.            {
  274.              NewFont
  275.            }
  276.            {
  277.              HSpace
  278.            } ifelse
  279.         } ifelse
  280.       } for
  281.       wordlen HSpace
  282.       /wtemp 0 def
  283.    } ifelse
  284. } bind def
  285.  
  286. %%%% Skipline skips a given amount of vertical space
  287. /SKIPLINE
  288. {
  289.    vspace 0 eq vspace vtotal gt or
  290.    {
  291.      vspace vtotal gt
  292.      {
  293.         /vspace vspace vtotal sub /vtotal vspace def def
  294.      } if
  295.   
  296.      /ytemp ypos def
  297.      true
  298.      20  % repeat
  299.      {
  300.         NextSpace not   % did it get a new line successfully?
  301.         {  
  302.            ENDPAGE STARTPAGE
  303.            /ypos baselineskip ypos add def /vtotal baselineskip def NEWLINE
  304.         } if
  305.         ypos ytemp ne { pop false exit } if
  306.      } repeat
  307.   
  308.      {       % Did the repeat "fail" by falling off the end?
  309.         erasepage
  310.         grestoreall
  311.         /Times-Roman findfont 20 scalefont setfont
  312.         50 100 moveto
  313.         (Could not place words anywhere on the virtual page) show
  314.         showpage
  315.         quit
  316.      } if
  317.    } if
  318. } bind def
  319.  
  320. %%%%%%%%%%%%%%%%%%%%%
  321. % Some startup definitions
  322. /para true def
  323. /vspace 0 def
  324.  
  325. % User command definitions, meant to be called from outside
  326. /NW { NextWord } bind def
  327. /SHOWIT { show } bind def
  328. /NEWLINE { PrintWordList NextSpace pop } def
  329. /NEWPARA
  330. {
  331.    PrintClose
  332.    /para true def
  333.    SKIPLINE
  334. } bind def
  335.  
  336. /ENUMERATE { dup stringwidth pop 9 add 
  337.              bslot exch sub ypos moveto show } bind def
  338. /BULLET
  339. {
  340.    newpath bslot 9 sub
  341.    ( ) stringwidth pop 1.7 div dup ypos add exch
  342.    0 360 arc currentgray 0 setgray fill setgray
  343. } bind def
  344.  
  345. /TIMESROMAN
  346. {
  347.   pop  /Times-Roman findfont 10 scalefont setfont
  348. } bind def
  349.  
  350. /VERBATIM
  351. {
  352.   bslot ypos moveto
  353.   dup length 0 gt
  354.   {
  355.      dup length 1 sub 0 1 3 -1 roll
  356.      {
  357.        1 index exch 1 getinterval
  358.        dup ( ) eq
  359.        {
  360.          stringwidth pop 0 rmoveto
  361.        }
  362.        {
  363.          show
  364.        } ifelse
  365.      } for
  366.      pop SKIPLINE
  367.   }
  368.   {
  369.     pop
  370.   } ifelse
  371. } bind def
  372.  
  373. /BASELINESKIP
  374. {
  375.   /baselineskip exch def
  376. } bind def
  377.  
  378. /STARTPAGE
  379. {
  380.   end
  381.   /savetype save def
  382.   StartPage
  383.   formatdict begin
  384.   InitWord
  385. } def
  386.  
  387. /ENDPAGE
  388. {
  389.   PrintClose
  390.   % Put all the variables we want to save on the stack
  391.   baselineskip bottommargin parindent justify rightmargin leftmargin
  392.   topmargin parskip newfontcmd para wordlen ypos ytemp
  393.   word type /stringtype eq
  394.   {
  395.     mark word {} forall true
  396.   }
  397.   {
  398.     word false
  399.   } ifelse
  400.   end
  401.  
  402.   savetype restore
  403.  
  404.   formatdict
  405.   begin
  406.      {
  407.        counttomark string /word exch def
  408.        counttomark 1 sub -1 0
  409.        {
  410.          exch word 3 1 roll put  % Builds word out of individual characters
  411.        } for
  412.        pop
  413.      }
  414.      {
  415.        /word exch def
  416.      } ifelse
  417.    
  418.      % Recover all the variables
  419.      /ytemp exch def /ypos exch def /wordlen exch def
  420.      /para exch def /newfontcmd exch def
  421.      /parskip exch def /topmargin exch def /leftmargin exch def
  422.      /rightmargin exch def /justify exch def /parindent exch def
  423.      /bottommargin exch def /baselineskip exch def
  424.   end
  425.   EndPage
  426.   formatdict begin
  427. } def
  428.